

package com.hazelcast.internal.partition.operation;

import com.hazelcast.internal.partition.InternalPartitionService;
import com.hazelcast.internal.partition.impl.PartitionDataSerializerHook;
import com.hazelcast.partition.PartitionService;
import com.hazelcast.spi.exception.TargetNotMemberException;
import com.hazelcast.spi.impl.AllowedDuringPassiveState;
import com.hazelcast.spi.impl.operationservice.ExceptionAction;

/**
 * Checks whether a node is safe or not.
 * Safe means, first backups of partitions those owned by local member are sync with primary.
 *
 * @see PartitionService#isClusterSafe
 * @see PartitionService#isMemberSafe
 */
public class SafeStateCheckOperation extends AbstractPartitionOperation implements AllowedDuringPassiveState {

    private transient boolean safe;
    private transient boolean throwWhenTargetNotMember;

    public SafeStateCheckOperation() {
    }

    public SafeStateCheckOperation(boolean throwWhenTargetNotMember) {
        this.throwWhenTargetNotMember = throwWhenTargetNotMember;
    }

    @Override
    public void run() throws Exception {
        final InternalPartitionService service = getService();
        safe = service.isMemberStateSafe();
    }

    @Override
    public Object getResponse() {
        return safe;
    }

    @Override
    public int getClassId() {
        return PartitionDataSerializerHook.SAFE_STATE_CHECK;
    }

    @Override
    public ExceptionAction onInvocationException(Throwable throwable) {
        return throwable instanceof TargetNotMemberException && throwWhenTargetNotMember ? ExceptionAction.THROW_EXCEPTION : super.onInvocationException(throwable);
    }
}
